﻿using NUnit.Framework;
using SW2A311_Lib;
using System;

namespace Unittest_on_lib
{
    [TestFixture]
    public class TaskTestSuite
    {
        #region TaskEnd
        [Test]
        public void TestTask_TaskEnd_LargerThanStart()
        {
            DateTime dEnd = new DateTime(3013, 06, 25);
            Task t = new Task(dEnd, DateTime.Now, "Navn1", "Dette er en test");
            Assert.IsTrue(dEnd > DateTime.Now);
        }
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestTask_TaskEnd_ExceptionThrown_EndTimeSmallerThanStart()
        {
            DateTime dEnd = new DateTime(2012, 06, 25);
            Task t = new Task(dEnd, DateTime.Now, "Navn1", "Dette er en test");
        }
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestTask_TaskEnd_ExceptionThrown_EndTimeIsZero()
        {
            DateTime dEnd = new DateTime();
            Task t = new Task(dEnd, DateTime.Now, "Navn1", "Dette er en test");
        }
        #endregion

        #region TaskStart
        [Test]
        public void TestTask_TaskStart_LowerThanEnd()
        {
            DateTime dStart = new DateTime(1013, 06, 25);
            Task t = new Task(DateTime.Now, dStart, "Navn1", "Dette er en test");
            Assert.IsTrue(dStart < DateTime.Now);
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestTask_TaskStart_ExceptionThrown_StartTimeNotDefined()
        {
            DateTime dStart = new DateTime();
            Task tTest = new Task(DateTime.Now, dStart, "Navn1", "Dette er en test");
        }
        #endregion

        #region TaskName
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestTask_TaskName_ExceptionThrown_NullOrWhitespace()
        {
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            Task tTest = new Task(DateTime.Now, DateTime.Now, "", "");

            pTest1.AddTask(tTest);
        }
        #endregion
    }

    [TestFixture]
    public class UserTestSuite
    {
        #region Username
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestUser_Username_ExceptioThrown_EmptyOrWhitespace()
        {
            string sNull = "";
            User u = new User(sNull, "123456");
        }
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestUser_Username_ExceptioThrown_TooShort()
        {
            string sShort = "Ib";
            User u = new User(sShort, "123456");
        }
        [Test]
        public void TestUser_Username_IsTrue()
        {
            string sTrue = "Rasmus Hove Johnsen";
            User u = new User(sTrue, "123456");
            Assert.IsTrue(sTrue == u.Username);
        }
        #endregion

        #region Password
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestUser_Password_ExceptioThrown_EmptyOrWhitespace()
        {
            string sNull = "";
            User u = new User("Rasmus Hove Johnsen", sNull);
        }
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestUser_Password_ExceptioThrown_TooShort()
        {
            string sShort = "123";
            User u = new User("Rasmus Hove Johnsen", sShort);
        }
        [Test]
        public void TestUser_Password_IsTrue()
        {
            string sTrue = "123456";
            User u = new User("Rasmus Hove Johnsen", sTrue);
            Assert.IsTrue(sTrue == u.Password);
        }
        #endregion
    }

    [TestFixture]
    public class ProjectDataTestSuite
    {
        #region DeleteTask
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestProjectData_DeleteTask_ExceptionThrown_TaskNotExist()
        {
            ProjectData pTest1 = new ProjectData("ProjektTest1", "Admin");
            Task t1 = new Task(DateTime.Now, DateTime.Now, "Task 1", "");
            Task t2 = new Task(DateTime.Now, DateTime.Now, "Task 2", "");

            pTest1.AddTask(t1);
            pTest1.AddTask(t2);

            pTest1.DeleteTask("Opan20");
        }
        [Test]
        public void TestProjectData_DeleteTask_TaskExists()
        {
            ProjectData pTest1 = new ProjectData("ProjektTest1", "Admin");
            Task t1 = new Task(DateTime.Now, DateTime.Now, "Task 1", "");
            Task t2 = new Task(DateTime.Now, DateTime.Now, "Task 2", "");

            pTest1.AddTask(t1);
            pTest1.AddTask(t2);

            pTest1.DeleteTask("Task 1");
        }
        #endregion

        #region AddTaskObject

        [Test]
        public void TestProjectData_AddTaskObject_TaskAdded()
        {
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            Task tTest = new Task(DateTime.Now, DateTime.Now, "Task 1", "");

            pTest1.AddTask(tTest);

            Assert.Contains(tTest, pTest1.TaskList);
        }
        [Test]
        public void TestProjectData_AddTaskObject_TaskOverridden()
        {
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            Task tTest1 = new Task(DateTime.Now, DateTime.Now, "Task 1", "");
            Task tTest2 = new Task(DateTime.Now, DateTime.Now, "Task 1", "");

            pTest1.AddTask(tTest1);
            pTest1.AddTask(tTest2);

            Assert.AreNotEqual(tTest1, pTest1.TaskList[0]);
        }
        #endregion

        #region AddTaskValue
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectData_AddTaskValue_ExceptionThrown_AlreadyExists()
        {
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            string sTest = "Task1";

            pTest1.AddTask(DateTime.Now, DateTime.Now, sTest, "Dette er en test");
            pTest1.AddTask(DateTime.Now, DateTime.Now, sTest, "Dette er endnu en test");
        }
        [Test]
        public void TestProjectData_AddTaskValue_TaskAdded()
        {
            string s = "Task 1";
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");

            pTest1.AddTask(DateTime.Now, DateTime.Now, s, "Dette er en test");
        }
        #endregion
    }

    [TestFixture]
    public class ProjectCollectionTestSuite
    {
        #region Constructor
        [Test]
        public void TestProjectCollection_Constructor_IsASingleton()
        {
            ProjectCollection pcTest1 = ProjectCollection.Instance;
            ProjectCollection pcTest2 = ProjectCollection.Instance;

            Assert.AreEqual(pcTest1, pcTest2);
        }
        #endregion

        #region AddProjectByName
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_AddProjectByName_ExceptionThrown_IsNullOrWhitespace()
        {
            string sTest = null;
            ProjectCollection pcTest1 = ProjectCollection.Instance;
            pcTest1.Add(sTest, "Admin");
        }
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_AddProjectByName_ExceptionThrown_AlreadyExists()
        {
            string sTest = "Project 1";
            ProjectCollection pcTest1 = ProjectCollection.Instance;
            pcTest1.Add(sTest, "Admin");
            pcTest1.Add(sTest, "Admin");
        }
        #endregion

        #region AddProjectByNameAndDate
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_AddProjectByNameAndDate_ExceptionThrown_IsNullOrWhitespace()
        {
            string sTest = null;
            DateTime dTest = DateTime.Now;
            ProjectCollection pcTest1 = ProjectCollection.Instance;
            pcTest1.Add(sTest, dTest, dTest, "Admin");
        }
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_AddProjectByNameAndDate_ExceptionThrown_AlreadyExists()
        {
            string sTest = "Project 1";
            DateTime dTest = DateTime.Now;
            ProjectCollection pcTest1 = ProjectCollection.Instance;
            pcTest1.Add(sTest, dTest, dTest, "Admin");
            pcTest1.Add(sTest, dTest, dTest, "Admin");
        }
        #endregion

        #region AddProjectByObject

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestProjectCollection_AddProjectByObject_ExceptionThrown_IsNull()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest = new ProjectData(null, "Admin");

            pcTest.Add(pTest);
        }
        [Test]
        public void TestProjectCollection_AddProjectByObject_NewProjectAdded()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");

            pcTest.Add(pTest1);

            Assert.AreEqual(pTest1, pcTest.FindProjectByName(pTest1.ProjectName));
        }
        [Test]
        public void TestProjectCollection_AddProjectByObject_ProjectOverridden()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            ProjectData pTest2 = new ProjectData("Project 1", "Admin");

            pcTest.Add(pTest1);
            pcTest.Add(pTest2);

            Assert.AreNotEqual(pTest1, pcTest.FindProjectByName(pTest1.ProjectName));
        }

        #endregion

        #region RemoveProject

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestProjectCollection_RemoveProject_ExceptionThrown_DoesntExist()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            string sTest = "Project 2";

            pcTest.Add(pTest1);
            pcTest.Remove(sTest);
        }

        #endregion

        #region FindProjectByName

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_FindProjectByName_ExceptionThrown_IsNull()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            string sTest = null;

            pcTest.Add(pTest1);
            pcTest.FindProjectByName(sTest);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestProjectCollection_FindProjectByName_ExceptionThrown_DoesntExist()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");
            string sTest = "Project 2";
            ProjectData pTest2;

            pcTest.Add(pTest1);
            pTest2 = pcTest.FindProjectByName(sTest);
        }

        [Test]
        public void TestProjectCollection_FindProjectByName_ProjectFound()
        {
            ProjectCollection pcTest = ProjectCollection.Instance;
            ProjectData pTest1 = new ProjectData("Project 1", "Admin");

            pcTest.Add(pTest1);
            Assert.AreEqual(pTest1, pcTest.FindProjectByName(pTest1.ProjectName));
        }

        #endregion

    }
}
